﻿using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Core.Framework.Common
{
    /// <summary>
    /// 延迟执行任务，并且禁止冒泡
    /// </summary>
    public class DelayExcuteAndDistinct
    {
        private ConcurrentQueue<CancellationTokenSource> _sourceHistory;
        private bool _isFirstTask = true;
        private TimeSpan _delayTime;

        public DelayExcuteAndDistinct(TimeSpan delayTime)
        {

            _delayTime = delayTime;
            _sourceHistory = new ConcurrentQueue<CancellationTokenSource>();

            var _source = new CancellationTokenSource();
            _sourceHistory.Enqueue(_source);
        }

        public void Execute(Action action)
        {
            CancellationTokenSource source;

            if (!_isFirstTask)
            {
                var sourceNew = new CancellationTokenSource();
                _sourceHistory.Enqueue(sourceNew);
                source = sourceNew;

                _sourceHistory.TryDequeue(out CancellationTokenSource result);
                result.Cancel(true);
            }
            else
            {
                _isFirstTask = false;
                source = _sourceHistory.Last();
            }

            Task.Run(async () =>
            {

                await Task.Delay(_delayTime, source.Token);

                try
                {
                    source.Token.ThrowIfCancellationRequested();
                    action.Invoke();
                    Console.WriteLine("WriteStateAsync 执行了");
                }
                catch (Exception ex)
                {
                    if (ex is OperationCanceledException canceled)
                    {
                        //Console.WriteLine("cancell");
                    }
                    else
                    {
                        throw ex;
                    }
                }
                finally
                {
                }
            });
        }

    }
}
